package com.smarttest.common.util;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.opera.core.systems.internal.StackHashMap;
import com.smarttest.common.beans.Result;
import com.smarttest.common.beans.TResult;
import com.smarttest.common.beans.TestResult;

public class InterfaceUtils {
	//初始化httpclient对象
	private static CloseableHttpClient httpclient;
	static {
		httpclient = HttpClients.createDefault();
	}
	public InterfaceUtils() {

	}
	protected static String Tlevel = "1";
	public static String getTlevel() {
		return Tlevel;
	}

	public static void setTlevel(String tlevel) {
		Tlevel = tlevel;
	}
//	private static Map<String,Object> actualrm = new HashMap<String, Object>();
//	public static Map<String, Object> getActualrm() {
//		return actualrm;
//	}
//	protected static Map<String, Map<Integer, Date>> msg_map = new HashMap<String, Map<Integer, Date>>();
//	public static Map<String, Map<Integer, Date>> getMsg_map() {
//		return msg_map;
//	}
	public void put(Map m, Object key, Object value) {
		if (m.containsKey(key)) {
			throw new RuntimeException("不能向map中添加重复key");
		}
		else {
			m.put(key, value);
		}
	}
	private static List<RockectMqProduce> rmqmap = new ArrayList<RockectMqProduce>();
	public static List<RockectMqProduce> getRmqmap() {
		return rmqmap;
	}

	/**
	 * 结束所有MQ生产者,并终止程序
	 */
	protected static void closeAllMQProducer() {
		Runtime.getRuntime().addShutdownHook(  
                new Thread()  
                {  
                    public void run(){  
                        //使用关闭钩子来关闭资源  
                    	for (RockectMqProduce rmq : rmqmap) {
                    		if(rmq != null){  
                                try{  
                                	rmq.close();  
                                }catch(Exception e){  
                                    e.printStackTrace();  
                                }  
                            } 
                    	}
                         
                        System.out.println("程序关闭了物理资源");  
                    }  
                }  
        );  
		System.exit(0);
	}
	/**
	 * 比较两个list是否相等
	 * @param list1
	 * @param list2
	 * @return
	 */
	public boolean equalList(List<?> list1, List<?> list2) {
        if (list1.size() != list2.size())
        {
            return false;
        }
        if (list2.containsAll(list1))
        {
            return true;
        }
        else {
            return false;
        }
	}
	
	/**
	 * 获得添加成功的结果对象
	 * 
	 * @param json
	 * @return Object
	 */
	public static Object getResult(JSONObject json) {
		// TODO Auto-generated method stub
		Object jsonResult = null;
		if (json.getIntValue("code") == 0) {
			jsonResult = json.getJSONObject("data").get("result") == null ? json
					.getJSONObject("data") : json.getJSONObject("data").get(
					"result");
		}
		return jsonResult;
	}
	
	
	/**
	 * 判断字符串是否为空或者NULL
	 * 
	 * @param str
	 *            字符串
	 * @return Boolean
	 */
	public static Boolean isStrEmpty(String str) {
		if (str == null || str.trim().length() == 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 将字符串转换成MD5编码
	 * 
	 * @param inStr
	 * @return String
	 */
	public static String string2MD5(String inStr) {
		String re_md5 = new String();
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(inStr.getBytes());
			byte b[] = md.digest();

			int i;

			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}

			re_md5 = buf.toString().toUpperCase();

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return re_md5;
	}
	/**
	 * 填充发送请求参数键值对
	 * 
	 * @param map
	 * @param Name
	 * @param Paras
	 * @param Method
	 * @param MD5String
	 * @param date
	 * @return List<BasicNameValuePair>
	 */
	public static List<BasicNameValuePair> fillData(Map<String, Object> map,
			String Name, String Paras, String Method, String MD5String,
			String date) {
		List<BasicNameValuePair> formparams = new ArrayList<BasicNameValuePair>();
		map.put("app_key", Name);
		map.put("method", Method);
		map.put("format", "json");
		map.put("timestamp", date);
		map.put("sign", string2MD5(MD5String));
		map.put("data", Paras);
		Iterator<String> iter = map.keySet().iterator();
		// System.out.print("Pram: ");
		while (iter.hasNext()) {
			String key = iter.next();
			String val = map.get(key).toString();
			formparams.add(new BasicNameValuePair(key, val));
		}
		// System.out.println();
		return formparams;
	}

	/**
	 * 比较时间先后
	 * 
	 * @param date1
	 * @param date2
	 * @param dateFormat
	 * @return Boolean
	 */
	public static Boolean isBeforeDate(String date1, String date2,
			String dateFormat) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, Locale.CHINA);
		Date d1 = null;
		Date d2 = null;
		try {
			d1 = sdf.parse(date1);
			d2 = sdf.parse(date2);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return d1.before(d2);
	}

	/**
	 * 把文本编码为Html代码
	 * 
	 * @param target
	 * @return 编码后的字符串
	 */
	public static String htmEncode(String target) {
		StringBuffer stringbuffer = new StringBuffer();
		int j = target.length();
		for (int i = 0; i < j; i++) {
			char c = target.charAt(i);
			switch (c) {
			case 60:
				stringbuffer.append("<");
				break;
			case 62:
				stringbuffer.append(">");
				break;
			case 38:
				stringbuffer.append("&");
				break;
			case 34:
				stringbuffer.append("\"");
				break;
			case 169:
				stringbuffer.append("©");
				break;
			case 174:
				stringbuffer.append("®");
				break;
			case 165:
				stringbuffer.append("¥");
				break;
			case 8364:
				stringbuffer.append("€");
				break;
			case 8482:
				stringbuffer.append("™");
				break;
			case 13:
				if (i < j - 1 && target.charAt(i + 1) == 10) {
					stringbuffer.append("<br>");
					i++;
				}
				break;
			case 32:
				if (i < j - 1 && target.charAt(i + 1) == ' ') {
					stringbuffer.append(" &nbsp;");
					i++;
					break;
				}
			default:
				stringbuffer.append(c);
				break;
			}
		}
		return new String(stringbuffer.toString());
	}

	/**
	 * 把中文转成Unicode码
	 * 
	 * @param str
	 * @return String
	 */
	public static String chinaToUnicode(String str) {
		String result = "";
		for (int i = 0; i < str.length(); i++) {
			int chr1 = str.charAt(i);
			if (chr1 >= 19968 && chr1 <= 171941) {// 汉字范围 \u4e00-\u9fa5 (中文)
				result += "\\u" + Integer.toHexString(chr1);
			} else {
				result += str.charAt(i);
			}
		}
		return result;
	}
	/**
	 * 对URL编码
	 * @param dest
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private static String getURLEncoder(String dest)
			throws UnsupportedEncodingException {
		return URLEncoder.encode(dest, "UTF-8");
	}
	/**
	 * 对入参进行处理
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public static String paramsconvert(Map<String, String> params) throws Exception{
		String paramsStr = "";
		int paramcount = 0;
		for (String key : params.keySet()) {
			String value = params.get(key);
			try {
				value = invokeMethod(value, Class.forName("com.smarttest.portal.function.paramsfunction.ParamsFunction"));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				StringWriter sw = new StringWriter();  
	            e.printStackTrace(new PrintWriter(sw, true));  
				throw new Exception("反射执行方法失败" + "\r\n" + sw.toString());
			} 
			if (paramcount == 0) {
				paramsStr += "?" + key + "=" + getURLEncoder(value);
			} else {
				paramsStr += "&" + key + "=" + getURLEncoder(value);
			}
			paramcount++;
		}
		return paramsStr;
	}


	/*
	 * 二行制转字符串
	 */
	private static String byte2hex(byte[] b) {

		StringBuffer hs = new StringBuffer();
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs.append("0").append(stmp);
			else
				hs.append(stmp);
		}
		return hs.toString().toUpperCase();
	}

	/*
	 * 签名方法，用于生成签名。
	 * 
	 * @param params 传给服务器的参数
	 * 
	 * @param secret 分配给您的APP_SECRET
	 */
	public static String sign2(Map params, String secret) {
		String result = null;
		if (params == null)
			return result;

		// 将参数按key排序
		Set<String> keys = params.keySet();
		String[] ps = new String[keys.size()];
		int i = 0;
		for (String key : keys) {
			Object value = params.get(key);
			if (value != null) {
				ps[i++] = key + value.toString();
			}
		}
		if (i == 0)
			return result;
		String[] ss = new String[i];
		System.arraycopy(ps, 0, ss, 0, i);
		Arrays.sort(ss);

		// 将secret同时放在头尾，拼成字符串
		StringBuilder orgin = new StringBuilder(secret);
		for (int j = 0; j < ss.length; j++) {
			orgin.append(ss[j]);
		}
		orgin.append(secret);

		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			result = byte2hex(md.digest(orgin.toString().getBytes("utf-8")));
		} catch (Exception ex) {
			throw new java.lang.RuntimeException("sign error !");
		}
		return result;
	}
	/**
	 * 调用dsp接口
	 * @param apiurl 接口调用地址
	 * @param sendmethod post/get
	 * @param callmethod 接口方法名
	 * @param format json/xml
	 * @param appkey appkey
	 * @param appsecret appsecret
	 * @param params 接口参数
	 * @return
	 * @throws Exception
	 */
	public static JSONObject callDspInterface(String apiurl, String sendmethod,String callmethod, String format, String appkey,String appsecret, Object...params) {
		Map<String,String> m =  new HashMap<String,String>();
		m.put("app_key", appkey);
		m.put("method", callmethod);
		m.put("format", format);
		
		// 时间戳
		m.put("timestamp", now("yyyy-MM-dd HH:mm:ss"));
		// 生成签名
		String sign = sign2(m, appsecret);
		// 组装协议参数sign
		m.put("sign", sign);
		for (int i = 0; i < params.length; i += 2) {
			m.put(String.valueOf(params[i]), String.valueOf(params[i+1]));
		}
		return callInterface(apiurl, sendmethod, m);
	}
	/**
	 * 调用接口
	 * 
	 * @param url url地址
	 * @param sendmethod 请求方式
	 * @param params 参数map
	 * @return JSONObject
	 */
	public static JSONObject callInterface(String apiurl, String sendmethod,
			Map<String, String> params){
		String paramsStr = null;
	CloseableHttpResponse response = null;
		try {
			paramsStr = paramsconvert(params);
			if (sendmethod.equalsIgnoreCase("post")) {
				HttpPost httppost = new HttpPost(apiurl);
				List<NameValuePair> paramss = new ArrayList<NameValuePair>();
				for (Map.Entry<String, String> entry : params.entrySet()) {
					paramss.add(new BasicNameValuePair(entry.getKey(),
							invokeMethod(entry.getValue(), Class.forName("com.smarttest.portal.function.paramsfunction.ParamsFunction"))));
				}
				httppost.setEntity(new UrlEncodedFormEntity(paramss, HTTP.UTF_8));
				response = httpclient.execute(httppost);
			} else if (sendmethod.equalsIgnoreCase("get")) {
				HttpGet httpget = new HttpGet(apiurl);
				httpget.setURI(new URI(httpget.getURI().toString() + "?"
						+ paramsStr));
				// 发送请求
				response = httpclient.execute(httpget);
			}
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			// 获取返回数据
			HttpEntity entity = response.getEntity();
//				ByteArrayOutputStream out = new ByteArrayOutputStream();
//				InputStream in = entity.getContent();
//				int len = 0;
//				byte[] buf = new byte[1024];
//				while((len=in.read(buf))!=-1){
//					out.write(buf, 0, len);
//				}
//				String resString = out.toString("UTF-8");
			String resString = null;
			try {
				resString = EntityUtils.toString(entity, "utf-8");
			} catch (org.apache.http.ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			JSONObject jsonobj = JSON.parseObject(resString);
			return jsonobj;
		} finally {
			try {
				response.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 调用接口
	 * 
	 * @param url 测试URL
	 * @param sendmethod  请求方式
	 * @param paramsStr 参数组合字符串
	 * @return JSONObject格式的数据
	 * @throws Exception
	 */
	public static JSONObject callInterface(String apiurl, String sendmethod,
			String paramsStr) throws ClientProtocolException, IOException {
		String URLString = apiurl + paramsStr;
		return callInterface(URLString, sendmethod);
	}

	/**
	 * 调用接口(通用)，发送请求,返回json字符串
	 * 
	 * @param url 接口测试URL（带参数）
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static JSONObject callInterface(String url, String sendMethod)
			throws ClientProtocolException, IOException {
		// CloseableHttpClient httpclient = HttpClients.createDefault();
		CloseableHttpResponse response = null;
		if (sendMethod.equalsIgnoreCase("post")) {

			HttpPost httppost = new HttpPost(url);
			response = httpclient.execute(httppost);
		} else if (sendMethod.equalsIgnoreCase("get")) {
			HttpGet httpget = new HttpGet(url);
			response = httpclient.execute(httpget);
		}
		try {
			HttpEntity myEntity = response.getEntity();
			String resString = EntityUtils.toString(myEntity, "utf-8");
			JSONObject jsonobj = JSON.parseObject(resString);
			return jsonobj;
		} finally {
			response.close();
		}
	}
	/**
	 * 字符串中文符号转英文符号
	 * @param str_CHN
	 * @return
	 */
	public static String strCHNToEN(String str_CHN) {
		String[] regs = { "！", "，", "。", "；", "【", "】", "“", "”", "!", ",",
				".", ";", "[", "]", "\"", "\"" };
		for (int i = 0; i < regs.length / 2; i++) {
			str_CHN = str_CHN.replaceAll(regs[i], regs[i + regs.length / 2]);
		}
		return str_CHN;
	}
	/**
	 * 判断STRING中是不是时间类型
	 * 
	 * @param str
	 *            String
	 * @param formatStr
	 *            时间格式
	 * @return boolean
	 */
	public static boolean isValidDate(String str, String formatStr) {
		boolean convertSuccess = true;
		// 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
		SimpleDateFormat format = new SimpleDateFormat(formatStr);
		try {
			// 设置lenient为false.
			// 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
			format.setLenient(false);
			format.parse(str);
		} catch (ParseException e) {
			// e.printStackTrace();
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			convertSuccess = false;
		}
		return convertSuccess;
	}

	/**
	 * 去掉数组中字符串中左右的空格
	 * 
	 * @param arr
	 * @return Object[] 处理后的数组
	 */
	public static Object[] trimArr(Object[] arr) {
		for (int i = 0; i < arr.length; i++) {
			arr[i] = arr[i].toString().trim();
		}
		return arr;
	}

	/**
	 * 将参数拆分（主要用于应对参数中有组合参数的情况，如a,"b1,b2,b3",c）
	 * 
	 * @param str
	 * @return String[] 处理后的数组
	 */
	public static Object[] splitSpecific(String str) {
		Object[] param;
		if (str.startsWith("{") && str.endsWith("}")) {
			String s1[] = str.split("\\},\\{");
			for (int i = 0; i < s1.length; i++) {
				s1[i] = s1[i].replaceAll("\\{", "").replaceAll("\\}", "")
						.trim();
			}
			return s1;
		} else if (str.startsWith("'") && str.endsWith("'")) {
			String s1[] = str.split("\',\'");
			for (int i = 0; i < s1.length; i++) {
				s1[i] = s1[i].replaceAll("\'", "").trim();
			}
			return s1;
		}

		else if (str.contains(",\"") || str.contains("\",")) {
			String s1[] = str.replaceAll(",\"", "\",").split("\",");
			for (int i = 0; i < s1.length; i++) {
				s1[i] = s1[i].replaceAll("\"", "").trim();
			}
			return s1;
		} else {
			param = str.split(",");
			param = trimArr(param);
			return param;
		}
	}

	/**
	 * 返回字符串str1中子串str2的个数
	 * 
	 * @param str1
	 * @param str2
	 * @return int
	 */
	public static int subCounter(String str1, String str2) {

		int counter = 0;
		for (int i = 0; i <= str1.length() - str2.length(); i++) {
			if (str1.substring(i, i + str2.length()).equalsIgnoreCase(str2)) {
				counter++;
			}
		}
		return counter;
	}

	/**
	 * php 获取Json的data信息
	 * 
	 * @param json
	 *            JSONObject
	 * @return JSONObject
	 */
	public static Object getJsonData(JSONObject json) {
		Object jsondata = json;
		while (((JSONObject) jsondata).containsKey("data")) {
			jsondata = ((JSONObject) jsondata).get("data");
			if (!(jsondata instanceof JSONObject)) {
				break;
			}
		}
		return jsondata;
		// while (json.containsKey("data")) {
		// json = json.getJSONObject("data");
		// }
		// return json;
	}

	/**
	 * php 获取Json的message信息
	 * 
	 * @param json
	 *            JSONObject
	 * @return String
	 */
	public static String getJsonMessage(JSONObject json) {
		String message = null;
		if (json.containsKey("data") && json.get("data") != null) {
			while (json.containsKey("data")) {
				if (json.containsKey("message")) {
					message = json.getString("message");
				} else if (json.getString("data").contains("\"message\"")) {
					if (json.get("data") instanceof JSONObject
							&& json.getJSONObject("data")
									.containsKey("message")) {
						message = json.getJSONObject("data").getString(
								"message");
					}
					if (json.get("data") instanceof JSONArray
							&& json.getJSONArray("data").getJSONObject(0)
									.containsKey("message")) {
						message = json.getJSONArray("data").getJSONObject(0)
								.getString("message");
					}
				}
				if (json.get("data") instanceof JSONObject) {
					json = json.getJSONObject("data");
				} else {
					break;
				}
			}
		} else {
			message = json.getString("message");
		}
		return message;
	}

	/**
	 * php 获取Json的code信息
	 * 
	 * @param json
	 *            JSONObject
	 * @return String
	 */
	public static String getJsonCode(JSONObject json) {
		String code = null;
		if (json.containsKey("data") && json.get("data") != null
				&& json.getString("data").contains("\"code\"")) {
			while (json.containsKey("data")) {
				if (json.get("data") instanceof JSONObject) {
					code = json.getString("code");
					json = json.getJSONObject("data");
				} else if (json.get("data") instanceof JSONArray) {
					code = json.getString("code");
					break;
				}
			}
		} else {
			code = json.getString("code");
		}
		return code;
	}

	/**
	 * 获得json result
	 * @param 返回json JSONObject
	 * @return String
	 */
	public static Object getJsonResult(JSONObject json) {
		Object jsonData = getJsonData(json);
		Object jsonResult = null;
		if (jsonData instanceof JSONObject) {
			if (((JSONObject) jsonData).containsKey("result")) {
				jsonResult = ((JSONObject) jsonData).get("result");
			} else {
				jsonResult = jsonData;
			}
		} else {
			jsonResult = jsonData;
		}
		return jsonResult;
	}

	public static Exception classForName(String cls) {
		Exception ex = null;
		try {
			Class.forName(cls);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			ex = e;
		}
		return ex;
	}
	private static String bracket = "BRACKET";

	/**
	 * 反射执行方法
	 * 
	 * @param s
	 * @param cls
	 *            执行哪个类中方法
	 * @return 执行方法后的字符串
	 * @throws InstantiationException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	public static String invokeMethod(String s, Class<?> cls) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
		StackHashMap<Integer, String> sh = new StackHashMap<Integer, String>();
		int count = 0;
		String tmpstr = s;
		Method ms[] = cls.getDeclaredMethods();
		Set<String> set = new HashSet<String>();
		for (int i = 0; i < ms.length; i++) {
			set.add(ms[i].getName());
		}
		while (!s.isEmpty()) {
			// 取字符串首字母
			String character = s.substring(0, 1);
			// 剩余的字符串
			s = s.substring(1);
			if (character.equals("(")) {
				sh.push(count, character);
			} else if (character.equals(")")) {
				if (sh.isEmpty())
					break;
				int index = sh.peekKey();
				sh.pop();
				String tmp = null;
				String method = getMethod(tmpstr.substring(0, index));
				if (!set.contains(method)) {
					count++;
					continue;
				}
				String paramsstr = tmpstr.substring(index + 1, count);
				
				if (paramsstr.contains("{") && paramsstr.contains("}")) {
					tmp = paramsstr.substring(paramsstr.indexOf("{") + 1,
							paramsstr.lastIndexOf("}"));
					paramsstr = paramsstr.substring(0,
							paramsstr.indexOf("{") + 1)
							+ bracket
							+ paramsstr.substring(paramsstr.lastIndexOf("}"));
				}
				else if (paramsstr.contains("[") && paramsstr.contains("]")) {
					tmp = paramsstr.substring(paramsstr.indexOf("[") + 1,
							paramsstr.lastIndexOf("]"));
					paramsstr = paramsstr.substring(0,
							paramsstr.indexOf("[") + 1)
							+ bracket
							+ paramsstr.substring(paramsstr.lastIndexOf("]"));
				}
				Object parammeters[] = splitSpecific(paramsstr);
				for (int i = 0; i < parammeters.length; i++) {
					String pm = parammeters[i].toString();
					if (pm.contains(bracket)) {
						if (tmp.contains("\\")){
							tmp = tmp.replaceAll("\\\\", "\\\\\\\\");
						}
						parammeters[i] = pm.replaceAll(bracket, tmp);
					}
				}
				parammeters = trimArr(parammeters);
				String invokeMethod = method
						+ tmpstr.substring(index, count + 1);
				Class<?>[] cArg = null;
				if (parammeters.length == 1
						&& parammeters[0].toString().isEmpty()) {

				} else {
					cArg = new Class[parammeters.length];
					for (int j = 0; j < cArg.length; j++) {
						cArg[j] = String.class;
					}
				}
				// InterfaceUtils inter = new InterfaceUtils();
				// Class<?> cls = InterfaceUtils.class;
				Method m1 = null;
				try {
					m1 = cls.getDeclaredMethod(method, cArg);
				} catch (NoSuchMethodException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					continue;
				}
				Object tmpresult = null;
				if (cArg == null) {
					tmpresult = m1.invoke(cls.newInstance());
				} else {
					tmpresult = m1.invoke(cls.newInstance(), parammeters);
				}
				String reslutStr;
				reslutStr = tmpresult == null ? ""
						: tmpresult instanceof Boolean ? String
								.valueOf(tmpresult) : tmpresult.toString();
				tmpstr = StringUtils.replaceOnce(tmpstr, invokeMethod,
						reslutStr);
				count += reslutStr.length() - invokeMethod.length();
			}
			count++;
			continue;
		}
		return tmpstr;
	}

	/**
	 * 反射执行字符串中方法
	 * 
	 * @param s
	 *            待执行其中方法的字符串
	 * @param cls
	 *            执行哪个类的方法
	 * @param clsinstance
	 *            反射执行该类方法的实例
	 * @return
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	public static String invokeMethod(String s, Class<?> cls, Object clsinstance) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		StackHashMap<Integer, String> sh = new StackHashMap<Integer, String>();
		// Stack<String> left=new Stack<String>();
		int count = 0;
		String tmpstr = s;
		Method ms[] = cls.getDeclaredMethods();
		Set<String> set = new HashSet<String>();
		for (int i = 0; i < ms.length; i++) {
			set.add(ms[i].getName());
		}
		while (!s.isEmpty()) {
			// 取字符串首字母
			String character = s.substring(0, 1);
			// 剩余的字符串
			s = s.substring(1);
			if (character.equals("(")) {
				sh.push(count, character);
			} else if (character.equals(")")) {
				if (sh.isEmpty())
					break;
				int index = sh.peekKey();
				String tmp = null;
				String method = getMethod(tmpstr.substring(0, index));
				if (!set.contains(method)) {
					count++;
					continue;
				}
				String paramsstr = tmpstr.substring(index + 1, count);
				if (paramsstr.contains("{") && paramsstr.contains("}")) {
					tmp = paramsstr.substring(paramsstr.indexOf("{") + 1,
							paramsstr.lastIndexOf("}"));
					paramsstr = paramsstr.substring(0,
							paramsstr.indexOf("{") + 1)
							+ bracket
							+ paramsstr.substring(paramsstr.lastIndexOf("}"));
				}
				else if (paramsstr.contains("[") && paramsstr.contains("]")) {
					tmp = paramsstr.substring(paramsstr.indexOf("[") + 1,
							paramsstr.lastIndexOf("]"));
					paramsstr = paramsstr.substring(0,
							paramsstr.indexOf("[") + 1)
							+ bracket
							+ paramsstr.substring(paramsstr.lastIndexOf("]"));
				}
				Object parammeters[] = splitSpecific(paramsstr);
				for (int i = 0; i < parammeters.length; i++) {
					String pm = parammeters[i].toString();
					if (pm.contains(bracket)) {
						if (tmp.contains("\\")){
							tmp = tmp.replaceAll("\\\\", "\\\\\\\\");
						}
						parammeters[i] = pm.replaceAll(bracket, tmp);
					}
				}
				parammeters = trimArr(parammeters);
				String invokeMethod = method
						+ tmpstr.substring(index, count + 1);
				Class<?>[] cArg = null;
				if (parammeters.length == 1
						&& parammeters[0].toString().isEmpty()) {

				} else {
					cArg = new Class[parammeters.length];
					for (int j = 0; j < cArg.length; j++) {
						cArg[j] = String.class;
					}
				}
				Method m1 = null;
				try {
					m1 = cls.getDeclaredMethod(method, cArg);
				} catch (NoSuchMethodException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					continue;
				}
				Object tmpresult = null;
				if (cArg == null) {
					tmpresult = m1.invoke(clsinstance);
				} else {
					tmpresult = m1.invoke(clsinstance, parammeters);
				}
				String reslutStr;
				reslutStr = tmpresult == null ? ""
						: tmpresult instanceof Boolean ? String
								.valueOf(tmpresult) : tmpresult.toString();
				tmpstr = StringUtils.replaceOnce(tmpstr, invokeMethod,
						reslutStr);
				count += reslutStr.length() - invokeMethod.length();
			}
			count++;
			continue;
		}
		return tmpstr;
	}

	/**
	 * 是否是字母、数字、下划线
	 * 
	 * @param str
	 * @return
	 */
	public static Boolean isMethodStr(String str) {

		Boolean bl = false;
		Pattern pt = Pattern.compile("[0-9a-zA-Z_]+");
		Matcher mt = pt.matcher(str);
		if (mt.matches()) {
			bl = true;
		}
		return bl;
	}

	/**
	 * 获得方法
	 * 
	 * @param str
	 * @return
	 */
	public static String getMethod(String str) {
		String method = "";
		while (!str.isEmpty()) {
			String lastchar = str.substring(str.length() - 1, str.length());
			// 剩余的字符串
			str = str.substring(0, str.length() - 1);
			if (!isMethodStr(lastchar)) {
				break;
			} else {
				method = lastchar + method;
			}
		}
		return method;
	}

	/**
	 * 检查断言是否正确
	 * @param str 传入断言的字符串
	 * @return 
	 * @throws ScriptException
	 */
	public static Boolean checkAssert(String str) throws ScriptException {
		ScriptEngineManager manager = new ScriptEngineManager();
		ScriptEngine engine = manager.getEngineByName("js");
		Object result = engine.eval(str);
		return (Boolean)result;
//		Assert.assertTrue((Boolean)result, "断言结果不正确:"+str);
	}
	
	/**
	 * 根据某文件及它与另一文件的相对路径获得另一文件
	 * @param file1
	 * @param relativefilepath
	 * @return
	 */
	public static File getRelativePathFile (String file1, String relativefilepath) {
		File file = null;
		File f = new File(file1).getParentFile();
		if (relativefilepath.startsWith("..\\")) {
			String []s  = relativefilepath.split("\\.\\.\\\\");
			for (int i = 0; i < s.length - 1; i++) {
				f = f.getParentFile();
			}
			file = new File(f, s[s.length-1]);
		}
		else {
			file = new File(f, relativefilepath);
		}
		return file;
	}
	/**
	 * 取当前时间
	 * @param timestamp 时间格式
	 * @return
	 */
	public static String now(String timestamp) {
		Date d = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat(timestamp);
		return sdf.format(d);
	}
	/**
	 * 接口测试
	 * @param arr 测试数据
	 * @return 
	 */
	public static TestResult interfaceTest (Object ... arr) {
		TestResult testresult = new TestResult();
		try {
			JSONObject iReturn = callInterface(arr[0].toString(), arr[1].toString(), (Map<String,String>)arr[2]);
			System.out.println(iReturn);
			String resultAlias = "";
			String expectReturn = "";
//			if(arr.length >= 11) {
//				if (arr[9] instanceof HashMap) {
//					for (Object key : ((HashMap<?, ?>)arr[9]).keySet()) {
//						if (key.toString().equalsIgnoreCase("resultAlias")) {
//							resultAlias = ((HashMap<?, ?>)arr[9]).get(key).toString();
//							break;
//						}
//						else if (key.toString().equalsIgnoreCase("expectReturn")) {
//							expectReturn = ((HashMap<?, ?>)arr[9]).get(key).toString();
//							break;
//						}
//					}
//				}
//				if (arr[10] instanceof HashMap) {
//					for (Object key : ((HashMap<?, ?>)arr[10]).keySet()) {
//						if (key.toString().equalsIgnoreCase("resultAlias")) {
//							resultAlias = ((HashMap<?, ?>)arr[10]).get(key).toString();
//							break;
//						}
//					}
//				}
//			}
//			
//			if (!resultAlias.isEmpty()) {
//				actualrm.put(resultAlias, getJsonResult(iReturn));
//			}
			testresult.setReturns(iReturn.toString());
			testresult.setResult(Result.PASS);
			if (!expectReturn.isEmpty()) {
				if (expectReturn.endsWith(".txt") || expectReturn.endsWith(".json") || expectReturn.endsWith(".xml") || expectReturn.endsWith(".properties")) {
					String expectreturn = org.apache.commons.io.FileUtils.readFileToString(getRelativePathFile("filename", expectReturn), "UTF-8");
					expectreturn = JSON.parse(expectreturn).toString();
					if (!iReturn.toJSONString().equalsIgnoreCase(expectreturn)) {
						testresult.setResult(Result.FAIL);
						testresult.setErrmsg("接口测试失败。ecpected return:" + expectreturn
								+ ",but actrual return:" + iReturn.toJSONString());
					}
				}
				else{
					if (!iReturn.toString().equalsIgnoreCase(expectReturn)) {
						testresult.setResult(Result.FAIL);
						testresult.setErrmsg("接口测试失败。ecpected return:" + expectReturn
								+ ",but actrual return:" + iReturn.toString());
					}
				}
			}			
			else {
				testresult = InterfaceCheck(iReturn,arr[3].toString(), arr[4].toString(), arr[5].toString(),arr[6].toString(),arr[7].toString());
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			testresult.setResult(Result.SKIP);
			StringWriter sw = new StringWriter();  
            e.printStackTrace(new PrintWriter(sw, true)); 
			testresult.setErrmsg("反射执行方法失败"+"\r\n"+sw.toString());
		}
		return testresult;
	}
	/**
	 * 接口返回验证
	 * @param json
	 * @param Paras
	 * @param code
	 * @param msg
	 * @param result
	 * @param resultnum
	 * @return
	 */
	public static TestResult InterfaceCheck(JSONObject json, String Paras,
			String code, String msg, String result, String resultnum) {
		TestResult testresult = new TestResult();
		testresult.setReturns(json.toString());
		testresult.setResult(Result.PASS);
		List<String> resultlist = new ArrayList<String>();
			try {
				result = invokeMethod(result, Class.forName("com.smarttest.portal.function.paramsfunction.ParamsFunction"));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				testresult.setResult(Result.SKIP);
				StringWriter sw = new StringWriter();  
	            e.printStackTrace(new PrintWriter(sw, true)); 
				testresult.setErrmsg("反射执行方法失败"+"\r\n"+sw.toString());
				return testresult;
			}
		if (!result.isEmpty()) {
			JSONObject resultjson = JSON.parseObject(result);
			for (String key : resultjson.keySet()) {
				resultlist.add(resultjson.getString(key));
			}
		}	
		String []resultarr = resultlist.toArray(new String[resultlist.size()]);
		String tmpcode = getJsonCode(json);
		String tmpmsg = getJsonMessage(json);
		Object jsonData = getJsonData(json);
		Object jsonResult = null;
		String resultStr;
		if (!tmpcode.equals(code)) {
			testresult.setResult(Result.FAIL);
			testresult.setErrmsg("返回的状态码：" + tmpcode + "与预期的状态码:" + code + "不一致");
			return testresult;
		} else {
			if (!isStrEmpty(msg)) {
				if (null == tmpmsg) {
					testresult.setResult(Result.FAIL);
					testresult.setErrmsg("接口测试失败。ecpected message:" + msg
							+ ",but actrual message:null");
					return testresult;
				}
				else if (!tmpmsg.contains(msg)){
					testresult.setResult(Result.FAIL);
					testresult.setErrmsg("接口测试失败。ecpected message:" + msg
							+ ",but actrual message:" + tmpmsg);
					return testresult;
				}				
			}
			jsonResult = getJsonResult(json);
			if (jsonResult instanceof JSONObject) {
				resultStr = ((JSONObject) jsonResult).toString();
				if (resultStr.equals("{}")) {
					if (!resultnum.equals("") && !resultnum.equals("0")) {
						testresult.setResult(Result.FAIL);
						testresult.setErrmsg("返回数据个数" + 0 + "与预期" + resultnum + "不一致");
						return testresult;
					}
				}
				// if (isStrEmpty(msg)) {
				// String [] tmp2 = Paras.split(",");
				// if (tmp2.length != ((JSONObject)jsonResult).size()) {
				// Reporter.log("接口返回信息:"+json.toString());
				// Assert.fail("返回数据参数个数" + ((JSONObject)jsonResult).size() +
				// "与预期" + tmp2.length + "不一致");
				// }
				// }
				else {
					if (!resultnum.equals("") && !resultnum.equals("1")) {
						testresult.setResult(Result.FAIL);
						testresult.setErrmsg("返回数据个数" + 1 + "与预期" + resultnum + "不一致");
						return testresult;
					}
					testresult = interfaceParamsCheck(json, jsonResult, resultarr);
				}
			} else if (jsonResult instanceof JSONArray) {
				JSONObject myJsonObject = JSON.parseObject(Paras);
				// 通过返回数据数组大小得出数据个数。但如果只显示了一页就有问题。所以应该通过totalcount判断，但目前这个参数有问题。所以暂时这样处理
				resultStr = String.valueOf(((JSONArray) jsonResult).size());
				if (jsonData instanceof JSONObject) {
					if (Integer.parseInt(resultStr) >= 1000
							&& ((JSONObject) jsonData)
									.containsKey("totalCount")) {
						resultStr = ((JSONObject) jsonData)
								.getString("totalCount");
					}
					if (Paras.contains("pageNo")
							&& ((JSONObject) jsonData).containsKey("pageNo")) {
						int count = ((JSONObject) jsonData)
								.getIntValue("totalCount");
						int psize = ((JSONObject) jsonData)
								.getIntValue("pageSize");
						int pnum = ((JSONObject) jsonData)
								.getIntValue("pageNo");
						if (count / psize + 1 < myJsonObject
								.getIntValue("pageNo")) {
							if (pnum != count / psize + 1
									&& pnum != myJsonObject
											.getIntValue("pageNo")) {
								testresult.setResult(Result.FAIL);
								testresult.setErrmsg("返回的pageno" + pnum + "与预期" + count
										/ psize + 1 + "不一致;");
								return testresult;
							}
						} else {
							if (pnum != myJsonObject.getIntValue("pageNo")) {
								testresult.setResult(Result.FAIL);
								testresult.setErrmsg("返回的pageno"
										+ ((JSONObject) jsonData)
										.getString("pageNo") + "与预期"
								+ myJsonObject.getString("pageNo")
								+ "不一致;");
								return testresult;
							}
						}
					}
					if (Paras.contains("pageNumber")
							&& ((JSONObject) jsonData)
									.containsKey("pageNumber")) {
						int count = ((JSONObject) jsonData)
								.getIntValue("totalCount");
						int psize = ((JSONObject) jsonData)
								.getIntValue("pageSize");
						int pnum = ((JSONObject) jsonData)
								.getIntValue("pageNumber");
						if (count / psize + 1 < myJsonObject
								.getIntValue("pageNumber")) {
							if (pnum != count / psize + 1
									&& pnum != myJsonObject
											.getIntValue("pageNumber")) {
								testresult.setResult(Result.FAIL);
								testresult.setErrmsg("返回的pageNumber" + pnum + "与预期"
										+ count / psize + 1 + "不一致;");
								return testresult;
							}
						} else {
							if (pnum != myJsonObject.getIntValue("pageNumber")) {
								testresult.setResult(Result.FAIL);
								testresult.setErrmsg("返回的pageNumber"
										+ ((JSONObject) jsonData)
										.getString("pageNumber")
								+ "与预期"
								+ myJsonObject.getString("pageNumber")
								+ "不一致;");
								return testresult;
							}
						}
					}
					if (Paras.contains("pageSize")
							&& ((JSONObject) jsonData).containsKey("pageSize")) {
						String size = myJsonObject.getString("pageSize");
						String pasize = ((JSONObject) jsonData)
								.getString("pageSize");
						if (size.equals("0")) {
							if (!pasize.equals("1000")) {
								testresult.setResult(Result.FAIL);
								testresult.setErrmsg("返回的pageSize" + pasize
										+ "与预期1000不一致;");
								return testresult;
							}
						} else {
							if (!pasize.equals(size)) {
								testresult.setResult(Result.FAIL);
								testresult.setErrmsg("返回的pageSize" + pasize + "与预期"
										+ size + "不一致;");
								return testresult;
							}
						}
					}
				}
				if (!isStrEmpty(resultnum)) {
					if (!resultStr.equals(resultnum)) {
						testresult.setResult(Result.FAIL);
						testresult.setErrmsg("接口调用成功，但返回数据条数" + resultStr + "与期望条数:"
								+ resultnum + "不一致");
						return testresult;
					}
				}
				if (Integer.parseInt(resultStr) > 0) {
					if (!isStrEmpty(result)) {
						// for (Object o : (JSONArray)jsonResult) {
						// interfaceParamsCheck(json, o, msg);
						// }
						testresult = interfaceParamsCheck(json, jsonResult, resultarr);
					}
				} else if (Integer.parseInt(resultStr) == 0
						&& !isStrEmpty(result)) {
					testresult.setResult(Result.FAIL);
					testresult.setErrmsg("返回0条数据,不存在与预期result的对比");
					return testresult;
				}
			} else {
				if (jsonResult == null) {
					resultStr = null;
				} else {
					resultStr = jsonResult.toString();
				}
				if (!isStrEmpty(result)) {
					testresult = interfaceParamsCheck(json, jsonResult, resultarr);
				}
			}
			// tmpmsg = json.get("message").toString();
		}
		return testresult;
	}
	/**
	 * 接口返回参数检查
	 * 
	 * @param json
	 *            接口返回json
	 * @param jsonResult
	 *            接口返回result
	 * @param result
	 *            期望result(excel中传入)
	 * @return 
	 * @throws ClassNotFoundException 
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 */
	public static TestResult interfaceParamsCheck(JSONObject json, Object jsonResult,
			String []result) {
		TestResult testresult = new TestResult();
		testresult.setReturns(json.toString());
		testresult.setResult(Result.PASS);
		for (String msgStr : result) {
			String tmparr[] = msgStr.split("\\(", 2);		
			String methodTotalName = tmparr[0].trim();
			String method = methodTotalName.substring(methodTotalName.lastIndexOf(".")+1);
			String classname = methodTotalName.substring(0,methodTotalName.lastIndexOf("."));	
			String assertstr = method+"("+tmparr[1];
			String tmps = tmparr[1]
					.substring(0, tmparr[1].lastIndexOf(")"));
			Object param[];
			Class<?>[] cArg = null;
			Class<?> cls = null;
			try {
				cls = Class.forName(classname);
			} catch (ClassNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
				testresult.setResult(Result.SKIP);
				testresult.setErrmsg("反射执行方法失败" + "\r\n" + e1.getMessage());
				return testresult;
			}
			Constructor<?> con = null;
			try {
				con = cls.getConstructor(String.class);
			} catch (NoSuchMethodException | SecurityException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
				testresult.setResult(Result.SKIP);
				testresult.setErrmsg("反射执行方法失败" + "\r\n" + e1.getMessage());
				return testresult;
			}
			if (tmps.trim().isEmpty()) {
				param = null;
			} else {
				if (method.equalsIgnoreCase("containsRs")) {
					param = new String[] { tmps };
					param = trimArr(param);
				} else {
					param = splitSpecific(tmps);
				}
				for (int i = 0; i < param.length; i++) {
					try {
						param[i] = invokeMethod(param[i].toString(),cls,con.newInstance(jsonResult.toString()));
					} catch (Exception e) {
						// TODO Auto-generated catch block
						testresult.setResult(Result.SKIP);
						StringWriter sw = new StringWriter();  
			            e.printStackTrace(new PrintWriter(sw, true)); 
						testresult.setErrmsg("反射执行方法失败" + "\r\n" + sw.toString());
						return testresult;
					} 
				}
				cArg = new Class[param.length];
				for (int i = 0; i < cArg.length; i++) {
					cArg[i] = String.class;
				}
			}				
			try {
				Method m1 = cls.getDeclaredMethod(method, cArg);
				Object o = m1.invoke(con.newInstance(jsonResult.toString()),param);
				if (o instanceof TResult) {
					Boolean tmpBol = ((TResult)o).getResult();
					String errdata = ((TResult)o).getErrData();
					if (tmpBol) {
						testresult.setResult(Result.PASS);
					}
					else {
						testresult.setResult(Result.FAIL);
						
						if (null != errdata && !errdata.isEmpty()) {
							testresult.setErrmsg("接口返回数据中存在数据"
									+ errdata + "不满足条件:"
									+ assertstr + "，接口测试失败");
						}
						else {
							testresult.setErrmsg("接口返回数据中存在数据"
									+ jsonResult.toString() + "不满足条件:"
									+ assertstr + "，接口测试失败");
						}
						return testresult;
					}
				}
				else if (o instanceof Boolean) {
					Boolean tmpBol = (Boolean)o ;
					if (!tmpBol) {
						testresult.setResult(Result.FAIL);
						testresult.setErrmsg("接口返回数据中存在数据"
								+ jsonResult.toString() + "不满足条件:"
								+ assertstr + "，接口测试失败");
						return testresult;
					}
				}
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				testresult.setResult(Result.SKIP);
				StringWriter sw = new StringWriter();  
	            e.printStackTrace(new PrintWriter(sw, true)); 
				testresult.setErrmsg("反射执行方法失败" + "\r\n" + sw.toString());
				return testresult;
			}
		}
		return testresult;
	}
}